package com.beans;

public class HandValuator implements IHandValuator 
{	
	public HandValue valuateHand( Hand pHand ) 
	{
		Card[] myHand = new Card[pHand.size()];
			
		for(int i = myHand.length - 1; i >= 0; i--)
		{
			myHand[i] = pHand.getHighCard();
			pHand.remove(myHand[i]);
		}
		
		for(int i=0; i < myHand.length; i++)
			pHand.add(myHand[i]);
		
		if(isStraightFlush(myHand))
			return new HandValue(HandValue.Category.STRAIGHT_FLUSH, pHand);
		
		if(isFourOfAKind(myHand))
			return new HandValue(HandValue.Category.FOUR_OF_A_KIND, pHand);
		
		if(isFullHouse(myHand))
			return new HandValue(HandValue.Category.FULL_HOUSE, pHand);
		
		if(isFlush(myHand))
			return new HandValue(HandValue.Category.FLUSH, pHand);
		
		if(isStraight(myHand))
			return new HandValue(HandValue.Category.STRAIGHT, pHand);
		
		if(isThreeOfAKind(myHand))
			return new HandValue(HandValue.Category.THREE_OF_A_KIND, pHand);
		
		if(isTwoPairs(myHand))
			return new HandValue(HandValue.Category.TWO_PAIRS, pHand);

		if(isPair(myHand))
			return new HandValue(HandValue.Category.PAIR, pHand);
			
		return new HandValue(HandValue.Category.HIGH_CARD, pHand);
	}
	
	private boolean isStraightFlush(Card[] myHand)
	{	
            int c=0;

            String color = null;

            int SPADES=0, DIAMONDS=0, HEARTS = 0, CLUBS=0;

            for(int i = 0; i < myHand.length - 1; i++)
            {
			if(myHand[i].getSuit().toString().equals("HEARTS"))
                             HEARTS++;
                        if(myHand[i].getSuit().toString().equals("CLUBS"))
                             CLUBS++;
                        if(myHand[i].getSuit().toString().equals("DIAMONDS"))
                             DIAMONDS++;
                        if(myHand[i].getSuit().toString().equals("SPADES"))
                             SPADES++;
            }
            if(HEARTS > 3)
                color="HEARTS";
            else if(CLUBS > 3)
                color="CLUBS";
            else if( DIAMONDS > 3)
                color="DIAMONDS";
            else if (SPADES > 3)
                color="SPADES";
            else
                return false;

            for(int i = 0; i < myHand.length - 1; i++)
                {
			if(myHand[i].compareTo(myHand[i+1]) == -1 && myHand[i].getSuit().toString().equals(color))
                            c++;
                        else
                        {
                            if (myHand[i].compareTo(myHand[i+1]) != 0)
                                c=0;
                            else
                                if(color.equals(myHand[i+1].getSuit().toString()) || color.equals(myHand[i].getSuit().toString()) )
                                {
                                    i++;
                                    c++;
                                }
                        }
                }

            if(c < 4)
                return false;
            else
		return true;
	}
	
	private boolean isFourOfAKind(Card[] myHand)
	{
		int c = 0; 

		for(int i=0 ; i < myHand.length ; i++)
                {
			if(myHand[i].compareTo(myHand[3]) == 0 && i!=3)
				c++;
                }
                
                if(c >= 3)
                    return true;
                else
                    return false;
	}
	
	private boolean isFullHouse(Card[] myHand)
	{
            
            for(int i =0 ; i < myHand.length-2 ; i++)
            {
                if(myHand[i].compareTo(myHand[i+2]) == 0 && i<4)
                {
                    for(int j=i+3 ; i<myHand.length-1 ; j++)
                    {
                        //System.out.println("j="+j);
                        if(myHand[j].compareTo(myHand[j+1]) == 0)
                        {
                            return true;
                        }
                    }
                }
                else
                {
                    if(myHand[i].compareTo(myHand[i+1])==0)
                    {
                        for(int j=i+2 ; j<myHand.length-2 ; j++)
                        {
                            if(myHand[j].compareTo(myHand[j+2]) == 0)
                                return true;
                        }
                    }
                }
            }
            return false;
	}
	
	private boolean isFlush(Card[] myHand)
	{
            int SPADES=0, DIAMONDS=0, HEARTS = 0, CLUBS=0;

		for(int i = 0; i < myHand.length - 1; i++)
		{
			if(myHand[i].getSuit().toString().equals("HEARTS"))
                             HEARTS++;
                        if(myHand[i].getSuit().toString().equals("CLUBS"))
                             CLUBS++;
                        if(myHand[i].getSuit().toString().equals("DIAMONDS"))
                             DIAMONDS++;
                        if(myHand[i].getSuit().toString().equals("SPADES"))
                             SPADES++;
		}
            
		if(HEARTS > 3 || SPADES > 3 || DIAMONDS > 3 || CLUBS > 3)
                    return true;

             return false;
	}
	
	private boolean isStraight(Card[] myHand)
	{
            int c=0;

		for(int i = 0; i < myHand.length - 1; i++)
                {
			if(myHand[i].compareTo(myHand[i+1]) == -1)
                            c++;
                        else if(myHand[i].compareTo(myHand[i+1]) != 0 && c<4)
                            c=0;
                }

            if(c < 4)
                return false;
            else
		return true;
	}
	
	private boolean isThreeOfAKind(Card[] myHand)
	{	
		int c = 0;

                for(int i = 0; i < myHand.length - 2 ; i++)
                {
			if(myHand[i].compareTo(myHand[i+2]) == 0)
				c++;
                }
                
                 if(c==1)
                     return true;
                 else
                    return false;
	}
	
	private boolean isTwoPairs(Card[] myHand)
	{
		int c = 0;

                for(int i = 0; i < myHand.length - 1 ; i++)
                {
			if(myHand[i].compareTo(myHand[i+1]) == 0)
                        {
				c++;
                                i++;
                        }
                }

                 if(c==2)
                     return true;
                 else
                    return false;
	}
	
	private boolean isPair(Card[] myCards)
	{	
		for(int i = 0; i < myCards.length - 1; i++)
			if(myCards[i].compareTo(myCards[i+1]) == 0)	
				return true;
		
		return false;
	}
}